package com.ray.business.strategy.order.create;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.ray.base.service.compose.GoodsService;
import com.ray.base.table.entity.BaseMaterialModel;
import com.ray.business.builder.BusinessBuilder;
import com.ray.business.builder.BusinessInBuilder;
import com.ray.business.check.BusinessOutCheck;
import com.ray.business.enums.BusinessStatusEnum;
import com.ray.business.enums.BusinessTypeEnum;
import com.ray.business.enums.OrderStatusEnum;
import com.ray.business.service.*;
import com.ray.business.service.compose.BusinessService;
import com.ray.business.service.compose.IndexService;
import com.ray.business.table.entity.*;
import com.ray.business.table.params.business.BusinessCreateParams;
import com.ray.common.BooleanValue;
import com.ray.common.ObjectValue;
import com.ray.common.SysMsgCodeConstant;
import com.ray.common.check.AbstractCheck;
import com.ray.magicBlock.Strategy;
import com.ray.magicBlock.anno.Block;
import com.ray.util.CodeSplitUtil;
import com.ray.validate.support.utils.ValidateUtil;
import com.ray.wms.service.WmsWarehouseStockDetailService;
import com.ray.wms.table.entity.WmsWarehouseStockDetail;
import com.ray.woodencreate.beans.LoginUser;
import com.ray.woodencreate.enums.YesOrNoEnum;
import com.ray.woodencreate.exception.BusinessExceptionFactory;
import com.ray.woodencreate.util.Assert;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author bo shen
 * @Description: 订单商品数据
 * @Class: PurchaseInService
 * @Package com.ray.wms.strategy.in
 * @date 2020/6/8 15:05
 * @company <p>Ray快速开发平台</p>
 * @updateRecord time(修改时间)  author(修改人)   desc(修改内容)
 */
@Slf4j
@Block(group = "createBusiness", strategy = "in", desc = "工艺商品物料新增")
public class InOrderCreateService implements Strategy<BusinessCreateParams, LoginUser, String> {

    @Autowired
    private ProdBusinessService prodBusinessService;
    @Autowired
    private ProdBusinessInService prodBusinessInService;
    @Autowired
    private ProdBusinessOutService prodBusinessOutService;
    @Autowired
    private WmsWarehouseStockDetailService wmsWarehouseStockDetailService;
    @Autowired
    private ProdStepService prodStepService;
    @Autowired
    private BusinessService businessService;
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private IndexService indexService;
    @Autowired
    private ProdOrderStepService prodOrderStepService;

    @Override
    public String execute(BusinessCreateParams createParams, LoginUser loginUser) {
        //Assert.hasLength(createParams.getEmployee(),"生产人员不能为空");
        BusinessBuilder businessBuilder = new BusinessBuilder();
        businessBuilder.append(createParams).appendType(BusinessTypeEnum.IN.getValue())
                .appendStatus(BusinessStatusEnum.UN_CHECK.getValue()).appendCreate(loginUser);
        final List<BigDecimal> quantity = new ArrayList<>();
        //查询工序是否产品转换
        ProdStep prodStep = prodStepService.queryStepByStepCode(createParams.getStepCode(), loginUser);
        new AbstractCheck<>(prodStep).checkNull("工序不存在");
        final BooleanValue booleanValue = new BooleanValue(false);
        //判断是否是最后一个工序 最后一个工序自动生成顺序
        ProdOrderStep prodOrderStep = prodOrderStepService.lastStep(CodeSplitUtil.getFirst(createParams.getGoodsCode()), loginUser);
        if (StrUtil.equals(prodOrderStep.getStepCode(), createParams.getStepCode())) {
            //最后一个工序
            booleanValue.setValue(true);
        }
        //判断是否是最后一个工序
        //查询当前工序的出库单
        List<ProdBusiness> prodBusinesses = prodBusinessService.listOutByOrderNoAndSetpCode(createParams.getOrderNo(), createParams.getStepCode(), createParams.getCustomerCode(), createParams.getGoodsCode(), loginUser);
        List<String> businessCodes = prodBusinesses.parallelStream().map(ProdBusiness::getBusinessCode).collect(Collectors.toList());
        //保存物料明细
        List<String> keys = new ArrayList<>();
        //序列号
        List<String> serialNumbers = new ArrayList<>();
        List<ProdBusinessIn> inList = createParams.getGoods().stream().map(businessGoodsParams -> {
            //没有序列号就生成
            if (StrUtil.isBlank(businessGoodsParams.getSerialNumber())) {
                businessGoodsParams.setSerialNumber(businessService.getNumber());
            }
            if (keys.contains(businessGoodsParams.getKey())) {
                log.info("物料重复:{}", JSON.toJSONString(businessGoodsParams));
                throw BusinessExceptionFactory.newException("物料重复");
            }
            keys.add(businessGoodsParams.getKey());
            //生成顺序号
            if (booleanValue.getValue()) {
                businessGoodsParams.setIndexSort(indexService.queryIndex(createParams.getOrderNo(), CodeSplitUtil.getFirst(createParams.getGoodsCode()), loginUser));
            }
            BusinessInBuilder businessInBuilder = new BusinessInBuilder().append(businessGoodsParams)
                    .appendBusinessCode(businessBuilder.getCode()).appendOrderNo(createParams.getOrderNo()).appendCreate(loginUser);
            //业务入库必填序列号
            // Assert.hasLength(businessGoodsParams.getSerialNumber(), "请填写序列号");
            //判断序列号是否存在仓库
           /**
            WmsWarehouseStockDetail wmsWarehouseStockDetail = wmsWarehouseStockDetailService.existByGoodsCodeAndNumber(businessGoodsParams.getGoodsCode(),
                    businessGoodsParams.getSerialNumber(), loginUser);
            if (ObjectUtil.isNotNull(wmsWarehouseStockDetail)) {
                log.info("商品：{}，序列号:{}，已经存在", wmsWarehouseStockDetail.getGoodsCode(), wmsWarehouseStockDetail.getSerialNumber());
                throw BusinessExceptionFactory.newException("序列号" + businessGoodsParams.getSerialNumber() + "已经存在");
            }**/
            if (serialNumbers.contains(businessGoodsParams.getSerialNumber())) {
                throw BusinessExceptionFactory.newException("序列号重复");
            }
            serialNumbers.add(businessGoodsParams.getSerialNumber());
            //判断是否关联唯一单号
            //查询数据信息
            ProdBusinessOut businessOut = null;
            if (prodStep.getGoodsStatus() == YesOrNoEnum.YES.getValue().intValue()) {
                businessOut = prodBusinessOutService.getOutGoodsByNumber(businessGoodsParams.getSerialNumber(), businessCodes, loginUser);
            } else {
                //查询数据信息
                businessOut = prodBusinessOutService.getOutGoodsByCode(businessGoodsParams, businessCodes, loginUser);
            }

            if (ObjectUtil.isNotNull(businessOut)) {
                if (businessOut.getStatus() == YesOrNoEnum.NO.getValue()) {
                    log.info("参数信息:{},businessCodes:{}", JSON.toJSONString(businessGoodsParams), businessCodes);
                    throw BusinessExceptionFactory.newException("数据已被使用");
                }
                //更新使用状态
                if (!prodBusinessOutService.useBusinessOut(businessOut.getCode(), businessOut.getUpdateVersion(), loginUser)) {
                    log.info("更新记录失败:{}", businessOut.getCode());
                    throw BusinessExceptionFactory.newException("更新记录异常");
                }
                businessInBuilder.appendOutCode(businessOut.getCode()).appendGangNo(businessOut.getGangNo());
            }
            quantity.add(businessGoodsParams.getQuantity());
            return businessInBuilder.bulid();
        }).collect(Collectors.toList());
        //保存总数
        businessBuilder.append(quantity.stream().reduce(BigDecimal::add).get());
        //保存
        prodBusinessService.save(businessBuilder.bulid());
        //保存数据
        prodBusinessInService.saveBatch(inList);
        return businessBuilder.getCode();
    }
}
